﻿#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="CameraManager3D.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2011
//       Roland Rosenkranz (Glatzemann@email.de)
// </copyright>
// <license>
//   This file is part of starLiGHT.Render.
//
//   starLiGHT.Render is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   starLiGHT.Core is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
//
//   You should have received a copy of the GNU Lesser General Public License
//   along with starLiGHT.Render. If not, see http://www.gnu.org/licenses/.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.Render are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev::                       $:  Revision of last commit *
// * $Author::                    $:  Author of last commit   *
// * $Date::                      $:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

#if !ZUNE

namespace starLiGHT.Camera.ThreeD
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using starLiGHT;
    using starLiGHT.Collections;
    using starLiGHT.Render.Camera;

    #endregion

    public class CameraManager3D : AbstractCameraManager
    {
        public CameraManager3D(GraphicsDevice graphicsDevice)
            : base(graphicsDevice)
        {
        }

        public override void ApplyCameraEffectParameters(ref Effect effect)
        {
            Camera3D activeCamera = this.ActiveCamera as Camera3D;

            if (activeCamera != null)
            {
                if (activeCamera == null || effect == null)
                {
                    return;
                }

                EffectParameter view = effect.Parameters.GetParameterBySemantic("VIEW");
                if (view != null)
                {
                    view.SetValue(activeCamera.View);
                }

                EffectParameter projection = effect.Parameters.GetParameterBySemantic("PROJECTION");
                if (projection != null)
                {
                    projection.SetValue(activeCamera.Projection);
                }

                EffectParameter viewProjection = effect.Parameters.GetParameterBySemantic("VIEWPROJECTION");
                if (viewProjection != null)
                {
                    viewProjection.SetValue(activeCamera.ViewProjection);
                }

                EffectParameter inverseViewProjection = effect.Parameters.GetParameterBySemantic("INVERSEVIEWPROJECTION");
                if (inverseViewProjection != null)
                {
                    inverseViewProjection.SetValue(activeCamera.InverseViewProjection);
                }

                EffectParameter screenSize = effect.Parameters.GetParameterBySemantic("SCREENSIZE");
                if (screenSize != null)
                {
                    Vector2 viewportSize = activeCamera.Viewport.Height > 0 && activeCamera.Viewport.Width > 0 ? activeCamera.Viewport.GetSize() : this.GraphicsDevice.GetSize();
                    screenSize.SetValue(viewportSize);
                }

                EffectParameter nearClip = effect.Parameters.GetParameterBySemantic("NEARCLIPPLANE");
                if (nearClip != null)
                {
                    nearClip.SetValue(activeCamera.NearClip);
                }

                EffectParameter farClip = effect.Parameters.GetParameterBySemantic("FARCLIPPLANE");
                if (farClip != null)
                {
                    farClip.SetValue(activeCamera.FarClip);
                }

                EffectParameter viewPos = effect.Parameters.GetParameterBySemantic("VIEWPOSITION");
                if (viewPos != null)
                {
                    viewPos.SetValue(activeCamera.Position);
                }

                EffectParameter frustCorners = effect.Parameters.GetParameterBySemantic("FRUSTUMCORNERS");
                if (frustCorners != null)
                {
                    Vector3[] cornersWS = activeCamera.Frustum.GetCorners();
                    Vector3[] cornersVS = new Vector3[cornersWS.Length];
                    Matrix matView = activeCamera.View;
                    Vector3.Transform(cornersWS, ref matView, cornersVS);
                    Vector3[] corners = new Vector3[cornersVS.Length / 2];
                    for (int i = 0; i < 4; i++)
                    {
                        corners[i] = cornersVS[i + 4];
                    }

                    Vector3 temp = corners[3];
                    corners[3] = corners[2];
                    corners[2] = temp;
                    frustCorners.SetValue(corners);
                }
            }
        }

        public override void Update(GameTime gameTime)
        {
            ////TODO: implement
        }
    }
}

#endif